package model.service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import model.OnScreen;
import model.Snippet;
import android.os.AsyncTask;
import android.util.Log;

public class ServiceConnection extends AsyncTask<Void, String, String> 
{
	private static final String TAG = ServiceConnection.class.getSimpleName();
	
	private final String BASE_URL = "http://192.168.30.231:1111/get";
	
	private String url;
	
	public ServiceConnection()
	{
		url = String.format("%s/%s/%s", BASE_URL, OnScreen.getInstance().getUpperLeft().toString(), OnScreen.getInstance().getLowerRight().toString());
	}
	
	@Override
	protected String doInBackground(Void...coords) 
	{				
		try 
		{
			return baseRequest(url);
		} 
		catch (Exception e) 
		{
			OnScreen.getInstance().notifyScreenWithToast("Unable to connect to server");
		}
		return null;
	}
	
	private String baseRequest(String url) throws Exception
	{
		// create and make the call
		HttpClient httpClient = new DefaultHttpClient();
        String responseString = null;
    	HttpGet getter = new HttpGet(url);
    	HttpResponse response = httpClient.execute(getter);
    	
    	// catch the response
        StatusLine statusLine = response.getStatusLine();        
        boolean connectionStatusIsEqualToOK = statusLine.getStatusCode() == HttpStatus.SC_OK;
        
        if(connectionStatusIsEqualToOK)
        {
        	//translate response to a String
        	ByteArrayOutputStream out = new ByteArrayOutputStream();
            response.getEntity().writeTo(out);
            responseString = out.toString();            
            out.close();
            
            return responseString;
        } 
        else
        {
            //Close connection
            response.getEntity().getContent().close();
            //sendMessage(R.id.connectionFailed, _id); // connectionfailed sends along the ID so the right holder can alert the view to this.
            throw new IOException(statusLine.getReasonPhrase());
        }
	}
	
	@Override
	protected void onPostExecute(String result) {
		handleResult(result);
	}
	
	private void handleResult(String result)
	{
		Log.d(TAG, String.format("result: %s", result));
		if(result == null)
		{
			OnScreen.getInstance().notifyScreenWithToast("Unable to connect to server");		
		}
		else if(result.trim().isEmpty())
		{
			OnScreen.getInstance().notifyScreenWithToast("Snippets not found");		// change later? what happens when no snippets are found in given range?	
		}
		else
		{
			
			ServiceBehaviour translator = createTranslator(result);
			
			// translate the result and send it to the handler
			try 
			{				
				HashMap<String, Snippet> screenSnippets = translator.translateResponse(result);
				OnScreen.getInstance().updateSnippetList(screenSnippets);
			}
			catch(Exception e)
			{
				Log.e(TAG,e.toString());
				OnScreen.getInstance().notifyScreenWithToast("Invalid Data"); 
			}
		}
	}
	
	private ServiceBehaviour createTranslator(String result)
	{
		if(result.startsWith("<")) // XML always starts with this token and JSON starts with spaces or [
		{
			// XML (temporarily says new JsonBehaviour because the translator has to be initialized in all paths
			return new JSONBehaviour();				
		}
		else
		{
			//JSON
			return new JSONBehaviour();
		}

	}	
}
